#ifndef DEBUG_H
#define DEBUG_H

#include "uart/uart.h"
#include "usnprintf.h"

#define LOG_DEBUG   1u
#define LOG_INFO    2u
#define LOG_WARN    3u
#define LOG_ERROR   4u

#ifndef LOG_DEFAULT
    #define LOG_DEFAULT  1u
#endif

#define DEBUG_WRITE(x, y) uart_write_block((const uint8_t*)x, y)
#define ASSERT_FAILED(...) uart_write_block((const uint8_t*)__VA_ARGS__, sizeof(__VA_ARGS__) - 1)

#define LOG(level, ...)                                                                         \
	do {                                                                                        \
		if((LOG_##level) >= LOG_DEFAULT) {                                                      \
			int chars_len = usnprintf(printf_buffer, sizeof(printf_buffer), "%s:", #level);     \
			DEBUG_WRITE(printf_buffer, chars_len);                                               \
			chars_len = usnprintf(printf_buffer, sizeof(printf_buffer), __VA_ARGS__);           \
			DEBUG_WRITE(printf_buffer, chars_len);                                               \
		}                                                                                       \
	} while (0)

#define LOG_NO_LABEL(level, ...) \
	do { \
		if((LOG_##level) >= LOG_DEFAULT) { \
			int chars_len = usnprintf(printf_buffer, sizeof(printf_buffer), __VA_ARGS__); \
			DEBUG_WRITE(printf_buffer, chars_len); \
		} \
	} while (0)

#define LOG_ASSERT(x)                                                                           \
	do {                                                                                        \
		if (__builtin_expect(!(x), 0)) {                                                        \
			ASSERT_FAILED("ASSERT FAILED: " #x " " __FILE__ ":" SC_DEBUG_STR(__LINE__) "\n");   \
		}                                                                                       \
	} while (0)
    
#endif
